package com.immersiondemo;

import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.Log;
import android.view.DisplayCutout;
import android.view.View;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowManager;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
 * @author wenwang.liu
 *         create by 2019/2/22 16:13.
 */

public class PFullScreenUtils {
    private static final String TAG="PFullScreenUtils";
    /**
     * 1.华为手机，小米手机是刘海屏，设置全屏时，状态栏还在但变成黑色的背景了。需要单独适配刘海屏，设置activity 的paddingTop为凹槽的高度
     *2.oppo手机设置全屏时，状态栏不存在，设置activity 的paddingTop为状态栏的高度
     */
    public static final int FLAG_NOTCH_SUPPORT=0x00010000;
    /**
     * 添加窗口 FLAG 的方式设置界面使用刘海区
     * @param window
     */
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public static void setFullScreenWindowLayoutInDisplayCutout(Context context,Window window) {
        if(Build.VERSION.SDK_INT == Build.VERSION_CODES.O){
            setHuaweiFullScreen(context,window);
            setXiaomiFullScreen(context,window);
            setVivoFullScreen(context,window);
        }else if(Build.VERSION.SDK_INT == Build.VERSION_CODES.P){
            WindowManager.LayoutParams lp = window.getAttributes();
            lp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
            window.setAttributes(lp);
        }
    }

    /**
     * 华为设备设置activity全屏,也判断了是否为华为手机
     * @param context
     * @param window
     */
    @TargetApi(Build.VERSION_CODES.KITKAT)
    private static void setHuaweiFullScreen(Context context, Window window){
        if(hasNotchInHuawei(context)){
            if (window == null) {
                return;
            }
            WindowManager.LayoutParams layoutParams = window.getAttributes();
            try {
                Class layoutParamsExCls = Class.forName("com.huawei.android.view.LayoutParamsEx");
                Constructor con = layoutParamsExCls.getConstructor(WindowManager.LayoutParams.class);
                Object layoutParamsExObj = con.newInstance(layoutParams);
                Method method = layoutParamsExCls.getMethod("addHwFlags", int.class);
                method.invoke(layoutParamsExObj, FLAG_NOTCH_SUPPORT);
            } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException |InstantiationException
                    | InvocationTargetException e) {
                Log.e("test", "hw add notch screen flag api error");
            } catch (Exception e) {
                Log.e("test", "other Exception");
            }
        }
    }
    private static void setXiaomiFullScreen(Context context, final Window window){
        if(hasNotchInXiaomi(context)){
            int flag = 0x00000100 | 0x00000200 | 0x00000400;
            try {
                Method method = Window.class.getMethod("addExtraFlags",
                        int.class);
                method.invoke(window, flag);
            } catch (Exception e) {
                Log.i(TAG, "addExtraFlags not found.");
            }
        }
    }
    private static void setVivoFullScreen(Context context, final Window window){
        if(hasNotchInVivo(context)){
            setFullScreenWithSystemUi(window,true);
        }
    }
    public static void setFullScreenWithSystemUi(final Window window, boolean setListener) {
        int systemUiVisibility = 0;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            systemUiVisibility |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
        }
        window.getDecorView().setSystemUiVisibility(systemUiVisibility);

        if (setListener) {
            window.getDecorView().setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
                @Override
                public void onSystemUiVisibilityChange(int visibility) {
                    if (visibility == 0) {
                        setFullScreenWithSystemUi(window, false);
                    }
                }
            });
        }
    }
    /**
     * 判断小米是否有刘海屏
     */
    public static boolean hasNotchInXiaomi(Context context){
       return SystemPropertiesProxy.getInt(context,"ro.miui.notch", 0)==1;
    }
    /**
     * 判断该华为手机是否刘海屏
     */
    private static boolean hasNotchInHuawei(Context context) {
        boolean hasNotch = false;
        try {
            ClassLoader cl = context.getClassLoader();
            Class HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");
            Method hasNotchInScreen = HwNotchSizeUtil.getMethod("hasNotchInScreen");
            if(hasNotchInScreen != null) {
                hasNotch = (boolean) hasNotchInScreen.invoke(HwNotchSizeUtil);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return hasNotch;
    }
    /**
     * 判断该Vivo手机是否刘海屏
     */
    public static boolean hasNotchInVivo(Context context) {
        boolean hasNotch = false;
        try {
            ClassLoader cl = context.getClassLoader();
            Class ftFeature = cl.loadClass("android.util.FtFeature");
            Method[] methods = ftFeature.getDeclaredMethods();
            if (methods != null) {
                for (int i = 0; i < methods.length; i++) {
                    Method method = methods[i];
                    if(method != null) {
                        if (method.getName().equalsIgnoreCase("isFeatureSupport")) {
                            hasNotch = (boolean) method.invoke(ftFeature, 0x00000020);
                            break;
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            hasNotch = false;
        }
        return hasNotch;
    }
    /**
     * 判断该Oppo手机是否刘海屏
     */
    public static boolean hasNotchInOppo(Context context){
        return context.getPackageManager().hasSystemFeature("com.oppo.feature.screen.heteromorphism");
    }

    /**
     * 获取刘海高度
     * @param context
     * @return
     */
    public static int[] getNotchSize(Context context) {
        int sizes[]=null;
        if(hasNotchInHuawei(context)){ //获取华为手机状态栏高度
            sizes=getHuaweiStatusHeight(context);
        }else if(hasNotchInXiaomi(context)){//获取小米手机状态栏高度
            sizes=getXiaomiStatusHeight(context);
        }else if(true){ //oppo手机状态栏高度
            sizes=getStatusBarHeight(context);
        }
        //获取vivo手机状态栏高度
       return sizes;
    }

    /**
     * 获取华为手机刘海高度
     * @param context
     * @return
     */
    private static int[] getHuaweiStatusHeight(Context context){
        int[] ret = new int[]{0, 0};
        try {
            ClassLoader cl = context.getClassLoader();
            Class HwNotchSizeUtil = cl.loadClass("com.huawei.android.util.HwNotchSizeUtil");
            Method get = HwNotchSizeUtil.getMethod("getNotchSize");
            ret = (int[]) get.invoke(HwNotchSizeUtil);
        } catch (ClassNotFoundException e) {
            ret=null;
            Log.e("test", "getNotchSize ClassNotFoundException");
        } catch (NoSuchMethodException e) {
            ret=null;
            Log.e("test", "getNotchSize NoSuchMethodException");
        } catch (Exception e) {
            ret=null;
            Log.e("test", "getNotchSize Exception");
        } finally {
            return ret;
        }
    }
    /**
     * 获取小米手机刘海高度
     * @param context
     * @return
     */
    private static int[] getStatusBarHeight(Context context) {//81
        int[] ret = new int[]{0, 0};
        int result = -1;
        int resourceId = context.getResources().getIdentifier("status_bar_height","dimen", "android");
        if (resourceId > 0) {
            result = context.getResources().getDimensionPixelSize(resourceId);
            ret[1]=result;
        }
        if(result==-1)ret=null;
        return ret;
    }
    //获取状态栏高度
    private static int[] getXiaomiStatusHeight(Context context) {
        int[] ret = new int[]{0, 0};
        int result=-1;
        int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = context.getResources().getDimensionPixelSize(resourceId);
            ret[1]=result;
        }
        if(result==-1)ret=null;
        return ret;
    }
}
